package com.forlove.app.manager;

import android.content.Intent;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;

import com.forlove.app.ForloveApplication;
import com.forlove.app.common.network.ICallBack;
import com.forlove.app.common.network.OkhttpManager;
import com.forlove.app.common.utils.LogUtil;
import com.forlove.app.common.utils.StringUtils;
import com.forlove.app.common.utils.SystemUtils;
import com.forlove.app.qselect.CommonEntity;
import com.forlove.app.qselect.login.entity.UserEntity;
import com.forlove.app.qselect.login.ui.ChoiceNewAgeActivity;

import org.json.JSONException;
import org.json.JSONObject;

import java.util.HashMap;
import java.util.Map;

/**
 * Created by yjl on 2017/10/16.
 */

public class NetworkManager {

    private NetworkManager() {
    }

    private static class NetworkConfig {
        private static NetworkManager networkManager = new NetworkManager();
        private static String mURL = ServerManager.getServerUrl();
        private static Map<Message, ICallBack> messageICallBackMap = new HashMap<>();
        private static Handler mHandler = new Handler(ForloveApplication.getInstance().getMainLooper()) {
            @Override
            public void handleMessage(Message msg) {
                try {
                    ICallBack CallBack = messageICallBackMap.get(msg);
                    if (CallBack != null) {
                        if (ResultCode.RESULT_NEED_LOGIN.getValue() == msg.what) {
                            UserManager.Logout();
                            CallBack.onFail(ResultCode.RESULT_NEED_LOGIN.getValue(), msg.obj.toString());
                            Intent intent = new Intent(ForloveApplication.getInstance(), ChoiceNewAgeActivity.class);
                            intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
                            ForloveApplication.getInstance().startActivity(intent);
                        } else if (ResultCode.RESULT_ERROR.getValue() == msg.what
                                || ResultCode.RESULT_FAIL.getValue() == msg.what
                                || ResultCode.RESULT_NETWORK_ERROR.getValue() == msg.what) {
                            CallBack.onFail(msg.what, msg.obj.toString());
                        } else if (ResultCode.RESULT_SUCCESS.getValue() == msg.what) {
                            CallBack.onSuccess(msg.what, msg.obj.toString());
                        } else if (200 != msg.what) {
                            CallBack.onFail(msg.what, msg.obj.toString());
                        }
                        messageICallBackMap.remove(msg);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        };

    }

    public static NetworkManager getInstance() {
        return NetworkConfig.networkManager;
    }

    public synchronized void clearRequest() {
        if (NetworkConfig.messageICallBackMap != null) {
            NetworkConfig.messageICallBackMap.clear();
        }
    }

    public void loadDataByGet(String action, final ICallBack mCallBack) throws Exception {
        if (!TextUtils.isEmpty(NetworkConfig.mURL) && !TextUtils.isEmpty(action)) {

            String url = addParamGet(NetworkConfig.mURL + action);
            OkhttpManager.getInstance().loadDataByGet(url, new ICallBack() {
                @Override
                public void onSuccess(int statusCode, String result) {
                    try {
                        chargeResultCorrect(statusCode, result, mCallBack);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }

                @Override
                public void onFail(final int statusCode, final String result) {
                    LogUtil.e("yjl", "onFail statusCode:" + statusCode + "   result:" + result);
                    try {
                        onFailCheck(statusCode, result, mCallBack);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    }

    public void loadDataByGet(String action, Map params, final ICallBack mCallBack) throws Exception {
        if (!TextUtils.isEmpty(NetworkConfig.mURL) && !TextUtils.isEmpty(action)) {
            String url = addParamGet(NetworkConfig.mURL + action);
            OkhttpManager.getInstance().loadDataByGet(url, params, new ICallBack() {
                @Override
                public void onSuccess(int statusCode, String result) {
                    try {
                        chargeResultCorrect(statusCode, result, mCallBack);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }

                @Override
                public void onFail(final int statusCode, final String result) {
                    LogUtil.e("yjl", "onFail statusCode:" + statusCode + "   result:" + result);
                    try {
                        onFailCheck(statusCode, result, mCallBack);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    }

    public void loadDataByPost(String action, String json, final ICallBack mCallBack) throws Exception {
        if (!StringUtils.isEmpty(action)) {
            OkhttpManager.getInstance().loadDataByPost(NetworkConfig.mURL + action, addParamJsonString(json), new ICallBack() {
                @Override
                public void onSuccess(int statusCode, String result) {
                    try {
                        chargeResultCorrect(statusCode, result, mCallBack);
                    } catch (Exception e) {
                        e.printStackTrace();

                    }
                }

                @Override
                public void onFail(final int statusCode, final String result) {
                    LogUtil.e("yjl", "onFail statusCode:" + statusCode + "   result:" + result);
                    try {
                        onFailCheck(statusCode, result, mCallBack);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    }

    /**
     * post方式不添加额外参数
     *
     * @param action
     * @param mCallBack
     * @throws Exception
     */
    public void loadDataByPost(final String action, final ICallBack mCallBack) throws Exception {
        loadDataByPost(action, new HashMap(), mCallBack);
    }

    public void loadDataByPost(final String action, final Map param, final ICallBack mCallBack) throws Exception {
        if (!StringUtils.isEmpty(action)) {
            OkhttpManager.getInstance().loadDataByPost(NetworkConfig.mURL + action, addParamPost(param), new ICallBack() {
                @Override
                public void onSuccess(int statusCode, String result) {
                    try {
                        LogUtil.e("yjl", "onSuccess:" + NetworkConfig.mURL + action
                                + "   param:" + param + "   \nresult:" + result);
                        chargeResultCorrect(statusCode, result, mCallBack);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }

                @Override
                public void onFail(final int statusCode, final String result) {
                    LogUtil.e("yjl", "onFail:" + NetworkConfig.mURL + action + "   param:" + param
                            + "  statusCode:" + statusCode + "\n   result:" + result);
                    try {
                        onFailCheck(statusCode, result, mCallBack);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    }

    private static void onFailCheck(final int statusCode, String result, ICallBack iCallBack) throws Exception {
        if (TextUtils.isEmpty(result)) {
            Message message = new Message();
            message.obj = result;
            message.what = statusCode;
            NetworkConfig.messageICallBackMap.put(message, iCallBack);
            NetworkConfig.mHandler.sendMessage(message);
        } else if (!TextUtils.isEmpty(result)) {
            CommonEntity commonEntity = new CommonEntity();
            commonEntity.parseJSONString(result);
            if (!TextUtils.isEmpty(commonEntity.message)) {
                Message message = new Message();
                message.obj = result;
                message.what = commonEntity.state;
                NetworkConfig.messageICallBackMap.put(message, iCallBack);
                NetworkConfig.mHandler.sendMessage(message);
            } else {
                Message message = new Message();
                message.obj = result;
                message.what = ResultCode.RESULT_ERROR.getValue();
                NetworkConfig.messageICallBackMap.put(message, iCallBack);
                NetworkConfig.mHandler.sendMessage(message);
            }

        }
    }

    /**
     * 判断返回值是否正确
     *
     * @param result
     */
    private static void chargeResultCorrect(int statusCode, final String result, ICallBack iCallBack) throws Exception {
        LogUtil.d(result);
        //判断是否要强制登录
        if (result != null && !TextUtils.isEmpty(result)) {
            CommonEntity commonEntity = new CommonEntity();
            commonEntity.parseJSONString(result);
            if (commonEntity.state == 1003) {
                Message message = new Message();
                message.obj = result;
                message.what = ResultCode.RESULT_NEED_LOGIN.getValue();
                NetworkConfig.messageICallBackMap.put(message, iCallBack);
                NetworkConfig.mHandler.sendMessage(message);
            } else if (commonEntity.state == ResultCode.RESULT_SUCCESS.getValue()) {
                Message message = new Message();
                message.obj = result;
                message.what = ResultCode.RESULT_SUCCESS.getValue();
                NetworkConfig.messageICallBackMap.put(message, iCallBack);
                NetworkConfig.mHandler.sendMessage(message);
            } else if (commonEntity.state == ResultCode.RESULT_FAIL.getValue()) {
                Message message = new Message();
                message.obj = result;
                message.what = commonEntity.state;
                NetworkConfig.messageICallBackMap.put(message, iCallBack);
                NetworkConfig.mHandler.sendMessage(message);
            }
        } else {
            Message message = new Message();
            message.obj = result;
            message.what = statusCode;
            NetworkConfig.messageICallBackMap.put(message, iCallBack);
            NetworkConfig.mHandler.sendMessage(message);
            return;
        }

    }

    public static String addParamGet(String url) {
        StringBuilder strbu = new StringBuilder(url);
        if (!TextUtils.isEmpty(url)) {
            if (!url.contains("?")) {
                strbu.append("?");
            } else {
                strbu.append("&");
            }
            strbu.append("mobile_type=android");
            String device_no = SystemUtils.getUserDeviceID();
            strbu.append("&device_no=").append(device_no);
            strbu.append("device_type=Android");
            if (UserManager.getUserLoginState(ForloveApplication.getInstance())) {
                UserEntity userEntity = UserManager.getUesrInfo(ForloveApplication.getInstance());
                if (userEntity != null) {
                    strbu.append("&user_id=").append(userEntity.userId);
                    strbu.append("&access_token=").append(userEntity.access_token);
                    strbu.append("&regId=").append(userEntity.regId);
                }
            }

        }
        return strbu.toString();
    }

    public static Map addParamPost(Map map) {
        if (map == null) {
            map = new HashMap();
        }
        map.put("mobile_type", "android");
        map.put("device_type", "Android");
        String device_no = SystemUtils.getUserDeviceID();
        map.put("device_no", device_no);
        if (UserManager.getUserLoginState(ForloveApplication.getInstance())) {
            UserEntity userEntity = UserManager.getUesrInfo(ForloveApplication.getInstance());
            if (userEntity != null) {
                map.put("user_id", userEntity.userId + "");
                map.put("access_token", userEntity.access_token);
                map.put("regId", userEntity.regId);
            }
        }
        return map;
    }

    private static String addParamJsonString(String json) {

        try {
            JSONObject jsonObject;
            if (StringUtils.isNotEmpty(json)) {
                jsonObject = new JSONObject(json);
            } else {
                jsonObject = new JSONObject();
            }
            jsonObject.put("mobile_type", "android");
            String device_no = SystemUtils.getUserDeviceID();
            jsonObject.put("device_no", device_no);
            if (UserManager.getUserLoginState(ForloveApplication.getInstance())) {
                UserEntity userEntity = UserManager.getUesrInfo(ForloveApplication.getInstance());
                if (userEntity != null) {
                    jsonObject.put("user_id", userEntity.userId + "");
                    jsonObject.put("access_token", userEntity.access_token);
                    jsonObject.put("regId", userEntity.regId);
                    jsonObject.put("device_type", "Android");
                }
            }
            return jsonObject.toString();
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return json;
    }

    public void postPic(final String action, Map param, final ICallBack mCallBack) throws Exception {
        if (!StringUtils.isEmpty(action)) {
//            CallBack = mCallBack;
            OkhttpManager.getInstance().postPic(NetworkConfig.mURL + action, addParamPost(param), new ICallBack() {
                @Override
                public void onSuccess(int statusCode, String result) {
                    LogUtil.e("onSuccess:" + NetworkConfig.mURL + action
                            + "   statusCode:" + statusCode + "    result:" + result);
                    try {
                        chargeResultCorrect(statusCode, result, mCallBack);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }

                @Override
                public void onFail(final int statusCode, final String result) {
                    LogUtil.e("onFail:" + NetworkConfig.mURL + action
                            + "   statusCode:" + statusCode + "    result:" + result);
                    try {
                        onFailCheck(statusCode, result, mCallBack);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    }

    public void clearImageCache(String path) {
        OkhttpManager.getInstance().clearImageCache(path);
    }

    public enum ResultCode {
        /**
         * 请求成功
         */
        RESULT_SUCCESS(1),
        /**
         * 请求结果失败
         */
        RESULT_FAIL(0),
        /**
         * 需要登录
         */
        RESULT_NEED_LOGIN(1003),
        /**
         * 系统错误
         */
        RESULT_ERROR(500),

        /**
         * 网关超时
         */
        RESULT_NETWORK_ERROR(504);

        private int mValue;

        ResultCode(int value) {
            mValue = value;
        }

        public int getValue() {
            return mValue;
        }
    }
}

